#!/usr/bin/python3
# -*- coding:utf-8 -*-
# @Time   :2021/12/8
# @Author :CJX
# @File   :main.py
import os
import sys
from typing import List, Union, Any
import RPi.GPIO as GPIO
import dht11
import can
import time
import numpy as np
from smbus import SMBus
from automatic_cleaning import automatic_cleaning
from remote_maintenance import remote_maintenance
from Injection_valve import injection_port
from Injection_valve import insert_database
from dox_enquiry import dox_command
from detection_relay_board import do_status
from detection_relay_board import di_status
from sql_insert import sql_insert_err
from sql_insert import sql_insert_suc
from threading import Thread
import threading

import pymysql

os.system('sudo ip link set can0 type can bitrate 250000')
os.system('sudo ifconfig can0 up')
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()


def restart_program():  # 程序重启函数，用于自动转手动过程中重启，加速反馈
    python = sys.executable
    os.execl(python, python, *sys.argv)


def DHT11():
    humidity_t = 0
    temperature_t1 = 0
    temperature_t2 = 0
    while 1:
        global err_inquiry_8, err_inquiry_12
        con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        address = "DHT11"
        instance = dht11.DHT11(pin=18)  # DHT11连接的引脚
        a = 0
        while a <= 10:
            result = instance.read()
            if result.is_valid():
                temperature = int(float('%-3.1f' % result.temperature))
                humidity = int(float('%-3.1f' % result.humidity))

                if humidity > 80:  # 环境湿度，可修改
                    dox_command([8], err_inquiry_8)
                    humidity_t = 1
                    sql_insert_err("环境湿度高")
                elif humidity < 80 and humidity_t == 1:
                    humidity_t = 0
                    dox_command([0], err_inquiry_8)
                    sql_insert_err("环境湿度正常")

                if temperature > 40:  # 环境温度，可修改
                    dox_command([8], err_inquiry_8)
                    temperature_t1 = 1
                    sql_insert_err("环境温度高")
                elif temperature < 35 and temperature_t1 == 1:
                    temperature_t1 = 0
                    dox_command([0], err_inquiry_8)
                    sql_insert_err("环境温度正常")

                if temperature < 5:  # 环境温度，可修改
                    temperature_t2 = 1
                    dox_command([12], err_inquiry_12)
                    sql_insert_err("环境温度低")
                elif temperature > 10 and temperature_t2 == 1:
                    temperature_t2 = 0
                    dox_command([0], err_inquiry_12)
                    sql_insert_err("环境温度正常")
                print("温度是： ", temperature, "湿度是： ", humidity)
                time1 = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                cur.executemany(
                    "INSERT DHT11(address,time,temperature,humidity) VALUE(%s,%s,%s,%s)",
                    [(address, time1, temperature, humidity)])
                con.commit()
                a = 11
            else:
                a = 0
        time.sleep(60)


def i2c_list():
    i2c_40_time = 0
    i2c_41_time = 0
    while 1:
        global err_inquiry, err_inquiry_26
        global err_inquiry_27, err_inquiry_28, err_inquiry_29
        con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        i2c_40 = cur.execute("SELECT i2c40 FROM i2c order by id desc limit 1")
        i2c_40 = int(cur.fetchone()[0])

        i2c_41 = cur.execute("SELECT i2c41 FROM i2c order by id desc limit 1")
        i2c_41 = int(cur.fetchone()[0])
        if i2c_40 <= 70 and i2c_40_time == 0:
            dox_command([26], err_inquiry_26)
            sql_insert_err("清洗液液位低")
            i2c_40_time = 1
        elif i2c_40 >= 90 and i2c_40_time == 1:
            dox_command([0], err_inquiry_26)
            i2c_40_time = 0

        if i2c_41 <= 70 and i2c_41_time == 0:
            dox_command([27], err_inquiry_27)
            sql_insert_err("保护液液位低")
            i2c_41_time = 1
        elif i2c_41 >= 90 and i2c_41_time == 1:
            dox_command([0], err_inquiry_27)
            i2c_41_time = 0
        cur.close()
        time.sleep(60)


def can_open():
    os.system('sudo ip link set can0 type can bitrate 250000')
    os.system('sudo ifconfig can0 up')


def io_restart():
    global status_restart_timing
    status_restart_timing = 1
    while status_restart_timing == 1:
        time.sleep(0.01)


def io_status():
    while 1:
        global status_restart_timing, io_status_quit
        time.sleep(0.1)
        if status_restart_timing == 1 and io_status_quit == 1:
            status_restart_timing = 0
            print("查询dido状态重启")
            io()


def io():
    while 1:
        global var1, var2, data_do, data_di  # 类型为list
        global falling_edge, rising_edge
        global di_location, do_location, err_inquiry, var_err_inquiry, err_inquiry_26
        global err_inquiry_27, err_inquiry_28, err_inquiry_29, err_inquiry_8, err_inquiry_12
        global status_restart_timing, io_status_quit, err_inquiry_22
        io_status_quit = 0
        bus = can.Bus(interface='socketcan', channel='can0', receive_own_messages=eval('False'))
        if status_restart_timing == 1:
            print("查询dido状态关闭")
            os.system('sudo ifconfig can0 down')
            can_open()
            io_status_quit = 1
            break
        # global edge, l_s_time  # 长按和短按判断，类型为array元素为True/False
        inquiry_do = can.Message(arbitration_id=0x0201, data=[0x01], is_extended_id=False)  # 问询
        bus.send(inquiry_do)  # 0x0201 DO状态 返回513
        message_do = bus.recv(timeout=1)  # 接收数据
        type_id_do = message_do.arbitration_id  # 返回can报文类型
        if type_id_do == 513:
            # time_float1 = message_do.timestamp          # 浮点数时间戳
            # time_date1 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(message_do.timestamp)))  # 转str时间
            # 取回4个字节,预留32通道,bytearray->int->bin(str)->去'0b'->bin->左补32位->反向排列
            data_do = '{:0>32b}'.format(int(bin(int.from_bytes(message_do.data[0:4], "little")).replace('0b', ''), 2))[
                      ::-1]
            # print(data_do, type(data_do))
            if var1 != data_do:  # 差异检测，差异写入数据库
                # write_sql(time_date1, type_id_do, data_do)+++++++++++注意排列顺序有修改
                var1 = data_do  # 给中间值赋新值
                do_location = list(data_do)
        time.sleep(0.1)
        # err_inquiry代表故障信号，用于dox_command的后半段中，防止故障信号被复原，err_inquiry_26代表除do_26以外的其他故障信号，以此类推。
        err_inquiry = err_inquiry_function(8) + err_inquiry_function(11) + err_inquiry_function(12) + \
                      err_inquiry_function(23) + err_inquiry_function(24) + \
                      err_inquiry_function(25) + err_inquiry_function(26) + err_inquiry_function(27) + \
                      err_inquiry_function(28) + err_inquiry_function(29)
        err_inquiry_26 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                         err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                         err_inquiry_function(7) + err_inquiry_function(8) + err_inquiry_function(9) + \
                         err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(12) + \
                         err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                         err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                         err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                         err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(27) + \
                         err_inquiry_function(28) + err_inquiry_function(29) + err_inquiry_function(30) + \
                         err_inquiry_function(31) + err_inquiry_function(32)
        err_inquiry_27 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                         err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                         err_inquiry_function(7) + err_inquiry_function(8) + err_inquiry_function(9) + \
                         err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(12) + \
                         err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                         err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                         err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                         err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(26) + \
                         err_inquiry_function(28) + err_inquiry_function(29) + err_inquiry_function(30) + \
                         err_inquiry_function(31) + err_inquiry_function(32)
        err_inquiry_28 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                         err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                         err_inquiry_function(7) + err_inquiry_function(8) + err_inquiry_function(9) + \
                         err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(12) + \
                         err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                         err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                         err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                         err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(27) + \
                         err_inquiry_function(26) + err_inquiry_function(29) + err_inquiry_function(30) + \
                         err_inquiry_function(31) + err_inquiry_function(32)
        err_inquiry_29 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                         err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                         err_inquiry_function(7) + err_inquiry_function(8) + err_inquiry_function(9) + \
                         err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(12) + \
                         err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                         err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                         err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                         err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(27) + \
                         err_inquiry_function(28) + err_inquiry_function(26) + err_inquiry_function(30) + \
                         err_inquiry_function(31) + err_inquiry_function(32)
        err_inquiry_8 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                        err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                        err_inquiry_function(7) + err_inquiry_function(29) + err_inquiry_function(9) + \
                        err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(12) + \
                        err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                        err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                        err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                        err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                        err_inquiry_function(25) + err_inquiry_function(27) + \
                        err_inquiry_function(28) + err_inquiry_function(26) + err_inquiry_function(30) + \
                        err_inquiry_function(31) + err_inquiry_function(32)
        err_inquiry_12 = err_inquiry_function(1) + err_inquiry_function(2) + err_inquiry_function(3) + \
                         err_inquiry_function(4) + err_inquiry_function(5) + err_inquiry_function(6) + \
                         err_inquiry_function(7) + err_inquiry_function(8) + err_inquiry_function(9) + \
                         err_inquiry_function(10) + err_inquiry_function(11) + err_inquiry_function(29) + \
                         err_inquiry_function(13) + err_inquiry_function(14) + err_inquiry_function(15) + \
                         err_inquiry_function(16) + err_inquiry_function(17) + err_inquiry_function(18) + \
                         err_inquiry_function(19) + err_inquiry_function(20) + err_inquiry_function(21) + \
                         err_inquiry_function(22) + err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(27) + \
                         err_inquiry_function(28) + err_inquiry_function(26) + err_inquiry_function(30) + \
                         err_inquiry_function(31) + err_inquiry_function(32)

        err_inquiry_22 = err_inquiry_function(8) + err_inquiry_function(11) + err_inquiry_function(12) + \
                         err_inquiry_function(23) + err_inquiry_function(24) + \
                         err_inquiry_function(25) + err_inquiry_function(26) + err_inquiry_function(27) + \
                         err_inquiry_function(28) + err_inquiry_function(29) + err_inquiry_function(22)
        # err_inquiry供dox_command函数使用，以免复位报警指令
        inquiry_di = can.Message(arbitration_id=0x0301, data=[0x01], is_extended_id=False)
        bus.send(inquiry_di)  # 0x0301  返回769/0x0301 di状态
        message_di = bus.recv(timeout=1)  # 接收数据
        type_id_di = message_di.arbitration_id  # 返回can报文类型
        if type_id_di == 769:
            # time_float2 = message_di.timestamp          # 浮点数时间戳
            # time_date2 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(float(message_di.timestamp)))  # 转str时间
            # 取回4个字,预留32通道,bytearray->int->bin(str)->去'0b'->bin->左补32位->反向排列
            data_di = '{:0>32b}'.format(int(bin(int.from_bytes(message_di.data[0:4], "little")).replace('0b', ''), 2))[
                      ::-1]
            # print(data_di, type(data_di))
            if data_di != var2:  # 差异检测，差异写入数据库
                # write_sql(time_date2, type_id_di, data_di)
                for k in range(32):
                    if var2[k] == '0' and data_di[k] == '1':  # 32点上升沿检测,没有检测到不复位
                        edge[0, k] = 1  # 写入边缘检测edge[0]
                        edge[1, k] = 0  # 复位下降沿
                        # time_diff[0, k] = time.time()  # 把时间写入array[0]，上升沿触发时间戳
                    if var2[k] == '1' and data_di[k] == '0':  # 32点下降沿检测,没有检测到不复位
                        edge[1, k] = 1  # 写入边缘检测edge[1]
                        edge[0, k] = 0  # 复位上升沿
                        # time_diff[1, k] = time.time()  # 把时间写入array[1]，下降沿触发时间戳
                    # l_s_time[0, k] = 0 < (time_diff[1, k] - time_diff[0, k]) < 3  # 短脉冲判断
                    # l_s_time[1, k] = 3 < (time_diff[1, k] - time_diff[0, k]) < 10  # 长脉冲判断
                    # print((time_diff[1, k] - time_diff[0, k]))
                var2 = data_di  # 给中间值赋新值
                di_location = list(data_di)  # 字符串转列表输出
                # print('下降沿', edge[1])
                # print('上升沿', edge[0])
                rising_edge = edge[0]
                falling_edge = edge[1]
        time.sleep(0.1)


def err_inquiry_function(err_num):  # 供dox_command函数使用，以免复位报警指令
    if do_location[err_num - 1:err_num][0] == "1":
        err_inquiry_num = [err_num]
    else:
        err_inquiry_num = [0]
    return err_inquiry_num


def manual_measurement_s1():
    global err_inquiry, support_failure, err_inquiry_22
    t = 0  # 计时使用
    dox_command([1], err_inquiry_22)  # 复位并输出DO1
    sql_insert_suc("手动测量")
    time.sleep(0.1)
    while t <= 60:  # 时限一分钟
        if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
            break
        if di_location[1:2][0] == "1":
            dox_command([0], err_inquiry_22)  # 复位DO1
            t = 70  # 成功后跳出循环
            sql_insert_suc("测量成功")
            break  # 输出测量状态
        else:
            t = t + 1  # 没成功时间计数+1
            time.sleep(1)
    if t > 60 and di_location[1:2][0] == "0":
        sql_insert_err("F-1测量指令故障")  # 可存入数据库
        sql_insert_err("支架故障")
        dox_command([23, 11], err_inquiry)  # 复位DO1,输出do23
        support_failure = 1  # 输出支架故障
        return


def manual_maintenance_s2():
    global err_inquiry, support_failure
    t = 0
    dox_command([22, 2], err_inquiry)  # 复位并输出DO22,DO2
    sql_insert_suc("手动检修")
    time.sleep(0.1)
    while t <= 60:
        if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
            break
        if di_location[2:3][0] == "1":
            dox_command([22], [0])  # 复位DO2
            t = 70
            sql_insert_suc("检修成功")
            pass  # 输出检修状态
        else:
            time.sleep(1)
            t = t + 1
    if t > 60 and di_location[2:3][0] == "0":
        sql_insert_err("F-2检修指令故障")  # 输出检修动作故障
        sql_insert_err("支架故障")
        dox_command([23, 11], err_inquiry)  # 复位DO2,输出do23
        support_failure = 1  # 输出支架故障
        return


def manual_curing_s3():
    global var1, var2, data_do, data_di
    global falling_edge, rising_edge
    global di_location, err_inquiry
    manual_curing_n = 2
    ver = 0  # 1为带自动冲洗，0为不带自动冲洗
    dox_command_t = 0
    if dox_command_t == 0:
        dox_command_t = 1
        dox_command([10, 22], err_inquiry)
        injection_port(0)  # 切换阀复位,X-0指令
        time.sleep(5)
        if insert_database() == "004d":  # 查询指令
            sql_insert_suc("切换阀初始化位置")
            pass  # 成功
        else:
            sql_insert_err("FX-0切换阀初始化故障")  # 可存入数据库
            dox_command([24], err_inquiry)
            return
    manual_curing_t2 = 0
    manual_curing_t3 = 0
    manual_curing_t5 = 0
    manual_curing_t8 = 0
    manual_curing_t9 = 0
    manual_curing_t10 = 0
    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 2:
        sql_insert_suc("手动保养中")

        print("步骤4")
        if ver == 1:
            dox_command([9, 10, 22], err_inquiry)  # 输出do9
            print("步骤6")
            while manual_curing_t2 <= 29:
                manual_curing_t2 = manual_curing_t2 + 1
                print("步骤6时停")
                time.sleep(1)
                if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
                    return
            manual_curing_n = 3
        else:
            manual_curing_n = 3

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 3:
        print("步骤7")
        manual_curing_n = 4

    if manual_curing_n == 4:
        print("步骤8")
        dox_command([10, 22], err_inquiry)  # 复位DO9

        injection_port(3)
        time.sleep(5)
        if insert_database() == "034d":  # 查询指令
            manual_curing_n = 5
            sql_insert_suc("切换阀水冲洗位置")
            pass  # 成功

        else:
            sql_insert_err("FX-3切换阀水冲洗位故障")  # 可存入数据库fx-3
            dox_command([24], err_inquiry)
            return

    if manual_curing_n == 5:
        print("步骤9")
        dox_command([3, 2, 10, 22], err_inquiry)  # 置位DO2

        while manual_curing_t3 <= 60:
            if di_location[2:3][0] == "1":
                dox_command([3, 10, 22], err_inquiry)  # 复位DO2
                manual_curing_t3 = 70
                sql_insert_suc("检修成功")
                pass  # 输出检修状态
            else:
                time.sleep(1)
                manual_curing_t3 = manual_curing_t3 + 1
        if manual_curing_t3 > 60 and di_location[2:3][0] == "0":
            sql_insert_err("F-2检修指令故障")  # 输出检修动作故障
            dox_command([23, 11], err_inquiry)
            time.sleep(1)
            return

        while manual_curing_t5 <= 24:
            print("步骤9时停")
            manual_curing_t5 = manual_curing_t5 + 1
            time.sleep(1)
            if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
                return
        dox_command([10, 22], err_inquiry)
        manual_curing_n = 7

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 7:
        print("步骤10")
        injection_port(0)
        time.sleep(5)
        injection_port(1)
        time.sleep(3)
        if insert_database() == "014d":  # 查询指令
            manual_curing_n = 8
            sql_insert_suc("切换阀清洗位置")
            pass  # 成功
        else:
            sql_insert_err("FX-2切换阀清洗位故障")  # 可存入数据库fx-2
            dox_command([24], err_inquiry)
            return
        time.sleep(2)

    if manual_curing_n == 8:
        dox_command([4, 10, 22], err_inquiry)
        print("步骤11")
        while manual_curing_t8 <= 7:
            manual_curing_t8 = manual_curing_t8 + 1
            time.sleep(1)
            if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
                return
        manual_curing_n = 9

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 9:
        dox_command([10, 22], err_inquiry)
        print("步骤12")
        while manual_curing_t9 <= 299:
            manual_curing_t9 = manual_curing_t9 + 1
            time.sleep(1)
            print("步骤12时停")
            if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
                return
        manual_curing_n = 10

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 10:
        injection_port(2)
        time.sleep(3)
        if insert_database() == "024d":  # 查询指令
            sql_insert_suc("切换阀保护位置")
            pass  # 成功
        else:
            sql_insert_err("FX-2切换阀保护位故障")  # 可存入数据库fx-2
            dox_command([24], err_inquiry)
            return
        dox_command([5, 10, 22], err_inquiry)
        print("步骤13")
        while manual_curing_t10 <= 11:
            manual_curing_t10 = manual_curing_t10 + 1
            time.sleep(1)
            if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
                return
        manual_curing_n = 11

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    if manual_curing_n == 11:
        print("步骤14")
        dox_command([22], err_inquiry)  # 复位do
        injection_port(0)  # 切换阀复位,X-0指令
        time.sleep(5)
        if insert_database() == "004d":  # 查询指令
            manual_curing_n = 12
            sql_insert_suc("切换阀初始化位置")
            pass  # 成功
        else:
            sql_insert_err("FX-0切换阀初始化故障")  # 可存入数据库
            dox_command([24], err_inquiry)
            return

    if manual_curing_n == 12:
        #  "输出养护中"
        print("步骤15")
        sql_insert_suc("手动保养结束")
        pass  #


def manual_cleaning_s4():
    global err_inquiry, support_failure
    sql_insert_suc("手动冲洗腔体中")
    injection_port(0)
    time.sleep(5)
    dox_command([22], err_inquiry)  # 输出do22
    injection_port(3)  # 切换阀复位,X-3指令

    if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
        return

    time.sleep(3)
    if insert_database() == "034d":  # 查询指令
        sql_insert_suc("切换阀水冲洗位置")
        pass  # 成功
    else:
        sql_insert_err("FX-3切换阀水冲洗位故障")  # 可存入数据库
        dox_command([24], err_inquiry)
        return

    dox_command([22, 3], err_inquiry)  # 输出do3
    while 1:
        if di_location[5:6][0] == "0":
            dox_command([22], err_inquiry)  # 复位DO3
            injection_port(0)  # 切换阀复位,X-3指令
            time.sleep(3)
            if insert_database() == "004d":  # 查询指令
                sql_insert_suc("切换阀复位成功")
                sql_insert_suc("手动冲洗腔体结束")
                pass  # 成功
                return
            else:
                sql_insert_err("切换阀复位故障FX-0")  # 可存入数据库
                dox_command([24], err_inquiry)
                return


def manually_replenish_cleaning_fluid_s5():
    global falling_edge, rising_edge, edge
    global err_inquiry, support_failure, err_inquiry_22
    dox_command([6, 17], err_inquiry_22)
    sql_insert_suc("补充清洗液中")
    while 1:
        con = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        i2c_40 = cur.execute("SELECT i2c40 FROM i2c order by id desc limit 1")
        i2c_40 = int(cur.fetchone()[0])
        time.sleep(0.2)
        cur.close()
        print(i2c_40)
        if i2c_40 >= 230 or falling_edge[6:7][0] == 1:  # 补充清洗液水位调整位置，更改i2c40的数值即可，可修改
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            dox_command([0], err_inquiry_22)
            sql_insert_suc("清洗液补充结束")
            break
        if di_location[0:1][0] == '1':
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            dox_command([0], err_inquiry_22)
            break


def manually_replenish_protective_fluid_s6():
    global falling_edge, rising_edge, edge
    global err_inquiry, support_failure, err_inquiry_22
    dox_command([7, 18], err_inquiry_22)  # 输出do7，do18
    sql_insert_suc("补充保护液中")
    while 1:
        con = pymysql.connect(
            host='localhost',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        i2c_41 = cur.execute("SELECT i2c41 FROM i2c order by id desc limit 1")
        i2c_41 = int(cur.fetchone()[0])
        time.sleep(0.2)
        cur.close()
        print(i2c_41)
        if i2c_41 >= 230 or falling_edge[7:8][0] == 1:  # 补充保护液水位调整位置，更改i2c41的数值即可,可修改
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            dox_command([0], err_inquiry_22)
            sql_insert_suc("保护液补充结束")
            break
        if di_location[0:1][0] == '1':
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            dox_command([0], err_inquiry_22)
            break


# 缓冲液4，缓冲液6按钮程序，暂时先注释
# def manually_replenish_buffer_4_s7():
#     global i2c_40, i2c_41
#     global falling_edge, rising_edge, edge
#     global err_inquiry, support_failure
#     dox_command([15, 19], err_inquiry)
#     while 1:
#         if i2c_42 >= 200 or falling_edge[11:12][0] == 1:
#             falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#                             0]
#             edge = np.zeros(64, np.int8).reshape(2, 32)
#             dox_command([0], err_inquiry)
#             break
#         if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#             break
#
#
# def delivery_buffer_4_s8():
#     global err_inquiry, support_failure
#     delivery_buffer_4_s8_t = 0
#     sql_insert_suc("输送一次 4.00 缓冲液")
#     dox_command([0], err_inquiry)
#     injection_port(1)
#     time.sleep(2)
#     if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#         return
#     dox_command([13], err_inquiry)
#     if insert_database() == "014d":  # 查询指令
#         sql_insert_suc("切换阀PH=4位置")
#         pass  # 成功
#     else:
#         sql_insert_err("FX-1切换阀PH=4位故障")  # 可存入数据库
#         dox_command([24], err_inquiry)
#         return
#
#     while delivery_buffer_4_s8_t < 8:
#         delivery_buffer_4_s8_t = delivery_buffer_4_s8_t + 1
#         time.sleep(1)
#         if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#             return
#         print(delivery_buffer_4_s8_t)
#     dox_command([0], err_inquiry)
#     injection_port(0)
#     time.sleep(2)
#     if insert_database() == "004d":  # 查询指令
#         sql_insert_suc("切换阀初始化位置")
#         pass  # 成功
#     else:
#         sql_insert_err("FX-0切换阀初始化故障")  # 可存入数据库
#         dox_command([24], err_inquiry)
#         return
#
#
# def manually_replenish_buffer_6_s9():
#     global i2c_40, i2c_41
#     global falling_edge, rising_edge, edge
#     global err_inquiry, support_failure
#     dox_command([16, 20], err_inquiry)
#     while 1:
#         if i2c_43 >= 200 or falling_edge[12:13][0] == 1:
#             falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#                             0]
#             edge = np.zeros(64, np.int8).reshape(2, 32)
#             dox_command([0], err_inquiry)
#             break
#         if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#             break
#
#
# def delivery_buffer_6_s10():
#     global err_inquiry, support_failure
#     delivery_buffer_6_s10_t = 0
#     sql_insert_suc("输送一次 6.86 缓冲液")
#     dox_command([0], err_inquiry)
#     injection_port(4)
#     time.sleep(2)
#
#     if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#         return
#     dox_command([14], err_inquiry)
#
#     if insert_database() == "044d":  # 查询指令
#         sql_insert_suc("切换阀PH=6位置")
#         pass  # 成功
#     else:
#         sql_insert_err("FX-4切换阀PH=6位故障")  # 可存入数据库
#         dox_command([24], err_inquiry)
#         return
#
#     while delivery_buffer_6_s10_t < 8:
#         delivery_buffer_6_s10_t = delivery_buffer_6_s10_t + 1
#         time.sleep(1)
#         if di_location[0:1][0] == '1' or di_location[30:31][0] == '1':
#             return
#         print(delivery_buffer_6_s10_t)
#     dox_command([0], err_inquiry)
#     injection_port(0)
#     time.sleep(2)
#     if insert_database() == "004d":  # 查询指令
#         sql_insert_suc("切换阀初始化位置")
#         pass  # 成功
#     else:
#         sql_insert_err("FX-0切换阀初始化故障")  # 可存入数据库
#         dox_command([24], err_inquiry)
#         return
def reset_all():
    dox_command([10, 17, 18], err_inquiry)


def Discharge_cleaning_fluid():
    global di_location, err_inquiry, err_inquiry_22
    print("排出清洗液")
    injection_port(0)
    time.sleep(3)
    injection_port(1)
    dox_command([4], err_inquiry_22)
    time.sleep(0.5)
    while di_location[6:7][0] == "1":
        time.sleep(0.1)
    dox_command([0], err_inquiry_22)
    time.sleep(0.1)
    injection_port(0)


def Discharge_protective_fluid():
    global di_location, err_inquiry, err_inquiry_22
    print("排出保护液")
    injection_port(0)
    time.sleep(3)
    injection_port(2)
    dox_command([5], err_inquiry_22)
    time.sleep(0.5)
    while di_location[7:8][0] == "1":
        time.sleep(0.1)
    dox_command([0], err_inquiry_22)
    time.sleep(0.1)
    injection_port(0)


def manual_control():
    maintain_t = 0  # 用于保养的计数
    reset_t = 0  # 用于复位按钮的计数
    Discharge_cleaning_fluid_t = 0
    Discharge_protective_fluid_t = 0
    manual_control_io_restart_t = 0  # 用于手动状态下查询io状态的复位
    do23_t1 = 0
    while 1:
        global falling_edge, rising_edge, di_location
        global edge, err_inquiry, manual_control_status
        global manual_control_reset_timing, err_inquiry_22
        if di_location[0:1][0] == "1":
            manual_control_status = 0
            break

        if di_location[1:2][0] == "1" and di_location[2:3][0] == "1" and do23_t1 == 0:
            do23_t1 = 1
            dox_command([11, 23], err_inquiry)

        if manual_control_reset_timing == 0:
            manual_control_reset_timing = 1
            if di_location[2:3][0] == "1":
                dox_command([22], err_inquiry)
            else:
                dox_command([0], err_inquiry)

        while di_location[6:7][0] == "1" and Discharge_cleaning_fluid_t <= 10:  # 手动排出清洗液计数，大于按的时间一秒即排出
            print(Discharge_cleaning_fluid_t)
            Discharge_cleaning_fluid_t = Discharge_cleaning_fluid_t + 1
            time.sleep(0.1)

        if Discharge_cleaning_fluid_t >= 10:
            Discharge_cleaning_fluid_t = 0
            Discharge_cleaning_fluid()
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)

        if falling_edge[6:7][0] == 1:  # 检测DI6的下降沿并复位
            Discharge_cleaning_fluid_t = 0
            print(falling_edge)
            print('手动补充清洗液')
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            manually_replenish_cleaning_fluid_s5()

        while di_location[7:8][0] == "1" and Discharge_protective_fluid_t <= 10:
            print(Discharge_protective_fluid_t)
            Discharge_protective_fluid_t = Discharge_protective_fluid_t + 1
            time.sleep(0.1)

        if Discharge_protective_fluid_t >= 10:
            Discharge_protective_fluid_t = 0
            Discharge_protective_fluid()
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)

        if falling_edge[7:8][0] == 1:  # 检测DI7的下降沿并复位
            Discharge_protective_fluid_t = 0
            print('手动补充保护液')
            falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                            0]
            edge = np.zeros(64, np.int8).reshape(2, 32)
            manually_replenish_protective_fluid_s6()

        if di_location[3:4][0] == "1" and di_location[1:2][0] == "0":
            manual_measurement_s1()
            print("测量")

        if di_location[4:5][0] == "1" and di_location[2:3][0] == "0":
            manual_maintenance_s2()
            print("检修")

        if 0 < maintain_t <= 10:
            maintain_t = 0
            manual_curing_s3()
            io_restart()
            print("保养")

        if maintain_t > 10:
            maintain_t = 0
            manual_cleaning_s4()
            io_restart()
            print("手动清洗")

        while di_location[5:6][0] == "1" and maintain_t <= 10:
            maintain_t = maintain_t + 1
            print(maintain_t)
            time.sleep(0.1)

        # 补充缓冲液4，补充缓冲液6程序，包含长按和短按
        # if 0 < buffer_4_t <= 30:
        #     buffer_4_t = 0
        #     falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        #                     0]
        #     edge = np.zeros(64, np.int8).reshape(2, 32)
        #     manually_replenish_buffer_4_s7()
        #     print("补充缓冲液4")
        #
        # if buffer_4_t > 30:
        #     buffer_4_t = 0
        #
        #     delivery_buffer_4_s8()
        #     print("输送缓冲液4")
        #
        # while di_location[11:12][0] == "1" and buffer_4_t <= 30:
        #     buffer_4_t = buffer_4_t + 1
        #     print(buffer_4_t)
        #     time.sleep(0.1)
        #
        # if 0 < buffer_6_t <= 30:
        #     buffer_6_t = 0
        #     falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        #                     0]
        #     edge = np.zeros(64, np.int8).reshape(2, 32)
        #     manually_replenish_buffer_6_s9()
        #     print("补充缓冲液6")
        #
        # if buffer_6_t > 30:
        #     buffer_6_t = 0
        #     delivery_buffer_6_s10()
        #     print("输送缓冲液6")
        #
        # while di_location[12:13][0] == "1" and buffer_6_t <= 30:
        #     buffer_6_t = buffer_6_t + 1
        #     print(buffer_6_t)
        #     time.sleep(0.1)

        while di_location[30:31][0] == "1" and reset_t <= 10:
            reset_t = reset_t + 1
            print(reset_t)
            time.sleep(0.1)

        if 0 < reset_t < 10:
            reset_t = 0

        if reset_t > 10:
            reset_t = 0
            if di_location[2:3][0] == "1":
                dox_command([22], [0])
            else:
                dox_command([0], [0])
            injection_port(0)
            time.sleep(3)
            if insert_database() == "004d":
                sql_insert_suc("切换阀复位成功")
            else:
                sql_insert_err("切换阀复位失败")
                dox_command([24], err_inquiry)
                return
        time.sleep(0.1)
        manual_control_io_restart_t = manual_control_io_restart_t + 1
        if manual_control_io_restart_t >= 300:
            manual_control_io_restart_t = 0
            io_restart()


def automatic_cleaning_s11():  # 自动清洗及校准顺控
    ver = 0  # 1为带自动冲洗，0为不带自动冲洗
    automatic_cleaning_n = 1
    while 1:
        global falling_edge, rising_edge, di_location
        global edge, err_inquiry
        global manual_control_status, remote_maintenance_status, automatic_cleaning_status
        automatic_cleaning_t2 = 0
        automatic_cleaning_t3 = 0
        automatic_cleaning_t4 = 0
        automatic_cleaning_t5 = 0
        automatic_cleaning_t6 = 0
        automatic_cleaning_t8 = 0
        automatic_cleaning_t9 = 0
        automatic_cleaning_t11 = 0
        automatic_cleaning_t100 = 0
        automatic_cleaning_t101 = 0
        automatic_cleaning_t102 = 0
        automatic_cleaning_t103 = 0
        automatic_cleaning_t30 = 0
        automatic_cleaning_n_7 = 0
        io_restart()
        dox_command([21], err_inquiry)
        time.sleep(1)
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        time.sleep(1)
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        time.sleep(1)
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        time.sleep(1)
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        time.sleep(1)
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        if automatic_cleaning_n == 1:
            print("自动清洗步骤1")
            sql_insert_suc("自动清洗模式")
            dox_command([21], err_inquiry)  # 复位do
            injection_port(0)  # 切换阀复位,X-0指令
            time.sleep(3)
            if insert_database() == "004d":  # 查询指令
                automatic_cleaning_n = 2
                sql_insert_suc("切换阀初始化位置")
                pass  # 成功
            else:
                sql_insert_err("FX—0切换阀初始化故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return
        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            break
        if automatic_cleaning_n == 2:
            print("步骤2")

            injection_port(3)  # x-3指令
            time.sleep(3)
            if insert_database() == "034d":  # 查询指令
                automatic_cleaning_n = 6
                sql_insert_suc("切换阀水冲洗位置")
                pass  # 成功
            else:
                sql_insert_err("FX-3切换阀水冲洗位故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return
            dox_command([3, 1, 21, 22], err_inquiry)  # 置位DO1

            while automatic_cleaning_t102 <= 5:
                automatic_cleaning_t102 = automatic_cleaning_t102 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return

            while automatic_cleaning_t2 <= 60:
                if di_location[1:2][0] == "1":
                    while automatic_cleaning_t103 <= 10:
                        automatic_cleaning_t103 = automatic_cleaning_t103 + 1
                        time.sleep(1)

                        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                            automatic_cleaning_status = 0
                            return
                    dox_command([21, 22], err_inquiry)  # 复位DO1
                    automatic_cleaning_n = 3
                    automatic_cleaning_t2 = 70
                    sql_insert_suc('测量成功')
                    pass  # 输出测量状态
                else:
                    automatic_cleaning_t2 = automatic_cleaning_t2 + 1
                    time.sleep(1)
            if automatic_cleaning_t2 > 60 and di_location[1:2][0] == "0":
                print("测量指令故障")
                sql_insert_err("F-1测量指令故障")  # 可存入数据库
                dox_command([23, 11], err_inquiry)  # 复位DO21,输出do23
                time.sleep(1)
                break
        io_restart()
        if automatic_cleaning_n == 3:
            print("步骤3")
            while automatic_cleaning_t3 <= 39:  # 延时四十秒每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t3 = automatic_cleaning_t3 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            dox_command([21], err_inquiry)  # 复位DO22
            automatic_cleaning_n = 4

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            print("退出成功")
            automatic_cleaning_status = 0
            return
        io_restart()

        con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        i2c_40 = cur.execute("SELECT i2c40 FROM i2c order by id desc limit 1")
        i2c_40 = int(cur.fetchone()[0])
        cur.close()
        i2c_40_io_restart = 0
        while i2c_40 <= 70:
            if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                automatic_cleaning_status = 0
                return
            time.sleep(1)
            print("清洗液不足")
            i2c_40_io_restart = i2c_40_io_restart + 1
            if i2c_40_io_restart >= 100:
                print("can通讯复位")
                i2c_40_io_restart = 0
                io_restart()

        if automatic_cleaning_n == 4:
            print("步骤4")
            automatic_cleaning_n4_io_restart = 0
            while automatic_cleaning_t4 <= 172800:  # 延时48h（172800秒）每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t4 = automatic_cleaning_t4 + 1
                time.sleep(1)
                automatic_cleaning_n4_io_restart = automatic_cleaning_n4_io_restart + 1
                if automatic_cleaning_n4_io_restart >= 100:
                    automatic_cleaning_n4_io_restart = 0
                    print("经典步骤四查询复位")
                    io_restart()
                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            dox_command([22, 21], err_inquiry)  # 输出DO22
            automatic_cleaning_n = 5

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 5:
            print("步骤5")
            if ver == 1:  # 进入步骤6
                print("步骤6")
                dox_command([9, 22, 21], err_inquiry)  # 输出DO9
                sql_insert_suc("自动程序，在线冲洗")
                while automatic_cleaning_t5 <= 29:  # 延时30秒每秒检测一次di状态，状态符合就退出循环
                    automatic_cleaning_t5 = automatic_cleaning_t5 + 1
                    time.sleep(1)
                    print(automatic_cleaning_t5)

                    if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                        automatic_cleaning_status = 0
                        return
                automatic_cleaning_n = 40
                automatic_cleaning_n_7 = 1
            else:
                automatic_cleaning_n = 40

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 40:
            if ver == 0 or automatic_cleaning_n_7 == 1:  # 步骤7
                print("步骤7")
                injection_port(3)  # x-3指令
                time.sleep(3)
                if insert_database() == "034d":  # 查询指令
                    automatic_cleaning_n = 6
                    sql_insert_suc("切换阀水冲洗位置")
                    pass  # 成功
                else:
                    sql_insert_err("FX-3切换阀水冲洗位故障")  # 可存入数据库
                    dox_command([24], err_inquiry)
                    return

                dox_command([3, 2, 9, 22, 21], err_inquiry)  # 置位DO2
                t = 0
                while t <= 60:
                    if di_location[2:3][0] == "1":
                        dox_command([3, 9, 22, 21], err_inquiry)  # 复位DO2
                        t = 70
                        pass  # 输出检修状态
                    else:
                        time.sleep(1)
                        t = t + 1
                if t > 60 and di_location[2:3][0] == "0":
                    sql_insert_err("F-2检修指令故障")  # 输出检修动作故障
                    dox_command([23, 11], err_inquiry)
                    time.sleep(1)
                    return

                while automatic_cleaning_t101 <= 5:
                    automatic_cleaning_t101 = automatic_cleaning_t101 + 1
                    time.sleep(1)

                    if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                        automatic_cleaning_status = 0
                        return

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 6:  # 步骤8
            print("步骤8")
            dox_command([3, 22, 21], err_inquiry)  # 复位DO9,输出DO3
            while automatic_cleaning_t6 <= 24:  # 延时25秒每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t6 = automatic_cleaning_t6 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            automatic_cleaning_n = 7

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 7:  # 步骤9
            print("步骤9")
            dox_command([22, 21], err_inquiry)  # 复位DO3
            injection_port(0)
            time.sleep(5)
            injection_port(1)  # x-1指令
            time.sleep(3)
            if insert_database() == "014d":  # 查询指令
                automatic_cleaning_n = 8
                sql_insert_suc("切换阀清洗位置")
                pass  # 成功
            else:
                sql_insert_err("FX-2切换阀清洗位故障")  # 可存入数据库fx-2
                dox_command([24], err_inquiry)
                return
        time.sleep(2)

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 8:  # 步骤10
            print("步骤10")
            dox_command([4, 22, 21], err_inquiry)  # 输出DO4

            while automatic_cleaning_t8 <= 7:  # 延时8秒每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t8 = automatic_cleaning_t8 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return

            automatic_cleaning_n = 9

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 9:  # 步骤11
            print("步骤11")
            dox_command([22, 21], err_inquiry)  # 复位DO4
            automatic_cleaning_t9_io = 0
            while automatic_cleaning_t9 <= 300:  # 延时5分钟每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t9 = automatic_cleaning_t9 + 1
                time.sleep(1)
                automatic_cleaning_t9_io = automatic_cleaning_t9_io + 1
                if automatic_cleaning_t9_io >= 100:
                    automatic_cleaning_t9_io = 0
                    print("经典步骤11重启io")
                    io_restart()

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            automatic_cleaning_n = 10

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 10:  # 步骤12
            print("步骤12")
            injection_port(0)
            time.sleep(5)
            injection_port(3)  # x-3指令
            time.sleep(3)
            if insert_database() == "034d":  # 查询指令
                automatic_cleaning_n = 11
                sql_insert_suc("切换阀水冲洗位置")
                pass  # 成功
            else:
                sql_insert_err("FX-3切换阀水冲洗位故障")  # 可存入数据库fx-3
                dox_command([24], err_inquiry)
                return

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 11:  # 步骤13
            print("步骤13")
            dox_command([3, 22, 21], err_inquiry)  # 输出DO3
            while automatic_cleaning_t11 <= 24:  # 延时24秒每秒检测一次di状态，状态符合就退出循环
                automatic_cleaning_t11 = automatic_cleaning_t11 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            t = 0
            dox_command([1, 3, 22, 21], err_inquiry)  # 置位DO1
            while t <= 60:
                if di_location[1:2][0] == "1":
                    dox_command([3, 22, 21], err_inquiry)  # 复位DO1
                    t = 70
                    sql_insert_suc('测量成功')
                    pass  # 输出测量状态
                else:
                    t = t + 1
                    time.sleep(1)
            if t > 60 and di_location[1:2][0] == "0":
                print("测量指令故障")
                sql_insert_err("F-1测量指令故障")  # 可存入数据库
                dox_command([3, 23, 11], err_inquiry)  # 复位DO21,输出do23
                time.sleep(1)
                break
            while automatic_cleaning_t100 <= 4:
                automatic_cleaning_t100 = automatic_cleaning_t100 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
                    automatic_cleaning_status = 0
                    return
            automatic_cleaning_n = 12

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 12:  # 步骤14
            print("步骤14")
            automatic_cleaning_n = 13

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            automatic_cleaning_status = 0
            return
        io_restart()
        if automatic_cleaning_n == 13:  # 步骤15
            print("步骤15")
            # if di_location[10:11][0] == "1":
            #     automatic_cleaning_n = 16
            #     pass  # 预留一个长效计数器作为C1, C1用处就是计算清洗次数，鉴于计数时间较长，建议存到数据库,每次到这+1
            #     C1 = 21  # 测试用
            # else:
            automatic_cleaning_n = 30

        # if automatic_cleaning_n == 16:  # 步骤16
        #     print("步骤16")
        #     if C1 >= 20:
        #         n = 17
        #     else:
        #         n = 30
        #
        # if automatic_cleaning_n == 17:  # 步骤17
        #     print("步骤17")
        #     injection_port(1)
        #     time.sleep(2)
        #     if insert_database() == "014d":  # 查询指令
        #         time.sleep(2)  # 延时两秒
        #         automatic_cleaning_n = 18
        #         pass  # 成功
        #     else:
        #         print("切换阀缓冲液4故障")  # 可存入数据库fx-1
        #
        # if automatic_cleaning_n == 18:  # 步骤18
        #     print("步骤18")
        #     dox_command([13, 22, 21], err_inquiry)  # 输出DO13
        #     time.sleep(15)
        #     automatic_cleaning_n = 19
        #
        # if automatic_cleaning_n == 19:  # 步骤19
        #     print("步骤19")
        #     dox_command([22, 21], err_inquiry)  # 复位DO13
        #     time.sleep(30)
        #     automatic_cleaning_n = 20
        #
        # if automatic_cleaning_n == 20:  # 步骤20
        #     print("步骤20")
        #     # 暂时没法写校准指令，无反馈
        #     # c2 = 1
        #     automatic_cleaning_n = 21
        #
        # if automatic_cleaning_n == 21:  # 步骤21
        #     print("步骤21")
        #     # 读反馈指令
        #     # if 正常 :
        #     #     n = 23
        #     # elif 不正常 and c2 < 2:
        #     #     n = 17
        #     # elif 不正常 and c2 > 2:
        #     #     # 输出故障f——JZ1
        #     #     n = 29
        #     automatic_cleaning_n = 23
        #
        # if automatic_cleaning_n == 23:  # 步骤23
        #     print("步骤23")
        #     C2 = 0
        #     injection_port(4)
        #     time.sleep(2)
        #     if insert_database() == "044d":  # 查询指令
        #         time.sleep(2)  # 延时两秒
        #         automatic_cleaning_n = 24
        #         pass  # 成功
        #     else:
        #         print("切换阀缓冲液6故障")  # 可存入数据库fx-4
        #
        # if automatic_cleaning_n == 24:
        #     print("步骤24")
        #     dox_command([14, 22, 21], err_inquiry)  # 输出DO14
        #     time.sleep(15)
        #     automatic_cleaning_n = 25
        #
        # if automatic_cleaning_n == 25:
        #     print("步骤25")
        #     dox_command([22, 21], err_inquiry)  # 复位DO14
        #     time.sleep(15)
        #     automatic_cleaning_n = 26
        #
        # if automatic_cleaning_n == 26:
        #     print("步骤26")
        #     # ph6校准指令，c2+1
        #     automatic_cleaning_n = 27
        #
        # if automatic_cleaning_n == 27:
        #     print("步骤27")
        #     # 读反馈指令
        #     # if 正常 :
        #     #     n = 29
        #     # elif 不正常 and c2<2:
        #     #     n =23
        #     # elif 不正常 and c2>2:
        #     #     输出故障F——JZ2
        #     #     n = 29
        #     automatic_cleaning_n = 29
        #
        # if automatic_cleaning_n == 29:
        #     print("步骤29")
        #     # 复位c1 c2
        #     automatic_cleaning_n = 30

        if automatic_cleaning_n == 30:
            automatic_cleaning_n = 2
            print("步骤30")
            # while automatic_cleaning_t30 <= 71:  # 延时24秒每秒检测一次di状态，状态符合就退出循环
            #     automatic_cleaning_t30 = automatic_cleaning_t30 + 1
            #     time.sleep(1)
            #     if di_location[0:1][0] == '0' or di_location[20:21][0] == '1':
            #         automatic_cleaning_status = 0
            #         return


def remote_maintenance_s12():  # 远程保养程序
    rm_n = 1
    ver = 0  # 1为带自动冲洗，0为不带自动冲洗
    remote_maintenance_t2 = 0
    remote_maintenance_t3 = 0
    while 1:
        global falling_edge, rising_edge, di_location
        global edge, err_inquiry
        global manual_control_status, remote_maintenance_status, automatic_cleaning_status
        remote_maintenance_t4 = 0
        remote_maintenance_t6 = 0
        remote_maintenance_t8 = 0
        remote_maintenance_t9 = 0
        remote_maintenance_t10 = 0

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break

        if rm_n == 1:
            print("步骤1")
            sql_insert_suc("远程保养中")
            dox_command([22, 10], err_inquiry)  # 复位do
            injection_port(0)  # 切换阀复位,X-0指令
            time.sleep(3)
            if insert_database() == "004d":  # 查询指令
                rm_n = 2
                sql_insert_suc("切换阀初始化位置")
                pass  # 成功
            else:
                sql_insert_err("FX—0切换阀初始化故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 2:
            print("步骤2")
            dox_command([21, 22, 10], err_inquiry)  # 输出DO21,DO22
            rm_n = 3

        if rm_n == 3:
            print("步骤3")
            if ver == 0:
                rm_n = 5
            if ver == 1:
                rm_n = 4

        if rm_n == 4:
            print("步骤4")
            dox_command([9, 21, 22, 10], err_inquiry)  # 输出DO9

            while remote_maintenance_t4 <= 29:  # 延时30秒每秒检测一次di状态，状态符合就退出循环
                remote_maintenance_t4 = remote_maintenance_t4 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                    remote_maintenance_status = 0
                    break
            rm_n = 5

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 5:
            print("步骤5")
            injection_port(3)  # 切换阀复位,X-3指令
            time.sleep(5)
            if insert_database() == "034d":  # 查询指令
                time.sleep(2)  # 延时两秒
                rm_n = 6
                sql_insert_suc("切换阀水冲洗位置")
                pass  # 成功
            else:
                sql_insert_err("FX——3切换阀水冲洗位故障")  # 可存入数据库f-3
                dox_command([24], err_inquiry)
                return
            dox_command([3, 2, 9, 22, 21, 10], err_inquiry)  # 置位DO2
            t = 0
            while t <= 60:
                if di_location[2:3][0] == "1":
                    dox_command([3, 9, 22, 21, 10], err_inquiry)  # 复位DO2
                    t = 70
                    pass  # 输出检修状态
                else:
                    time.sleep(1)
                    t = t + 1
            if t > 60 and di_location[2:3][0] == "0":
                sql_insert_err("F-2检修指令故障")
                dox_command([23, 11], err_inquiry)
                time.sleep(1)
                return  # 输出检修动作故障

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 6:
            print("步骤6")
            dox_command([3, 22, 21, 10], err_inquiry)  # 复位DO9,输出DO3
            while remote_maintenance_t6 <= 29:  # 延时30秒每秒检测一次di状态，状态符合就退出循环
                remote_maintenance_t6 = remote_maintenance_t6 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                    remote_maintenance_status = 0
                    break
            rm_n = 7

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 7:
            print("步骤7")
            dox_command([22, 21, 10], err_inquiry)  # 复位DO3
            injection_port(0)
            time.sleep(5)
            injection_port(1)  # x-1指令
            time.sleep(5)
            if insert_database() == "014d":  # 查询指令
                rm_n = 8
                sql_insert_suc("切换阀清洗位置")
            else:
                sql_insert_err("FX—3切换阀水冲洗位故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break

        if rm_n == 8:
            print("步骤8")
            dox_command([4, 22, 21, 10], err_inquiry)  # 输出DO4
            while remote_maintenance_t8 <= 7:  # 延时7秒每秒检测一次di状态，状态符合就退出循环
                remote_maintenance_t8 = remote_maintenance_t8 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                    remote_maintenance_status = 0
                    break
            rm_n = 9

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 9:
            print("步骤9")
            dox_command([22, 21, 10], err_inquiry)  # 复位DO4
            while remote_maintenance_t9 <= 299:  # 延时300秒每秒检测一次di状态，状态符合就退出循环
                remote_maintenance_t9 = remote_maintenance_t9 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                    remote_maintenance_status = 0
                    break
            rm_n = 10

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 10:
            print("步骤10")
            injection_port(0)
            time.sleep(5)
            injection_port(2)  # x-2指令
            time.sleep(5)
            if insert_database() == "024d":  # 查询指令
                sql_insert_suc("切换阀保护位置")
            else:
                sql_insert_err("FX—3切换阀水保护位故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return
            dox_command([5, 22, 21, 10], err_inquiry)  # 输出DO5
            while remote_maintenance_t10 <= 11:  # 延时12秒每秒检测一次di状态，状态符合就退出循环
                remote_maintenance_t10 = remote_maintenance_t10 + 1
                time.sleep(1)

                if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                    remote_maintenance_status = 0
                    break
            rm_n = 11

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 11:
            print("步骤11")
            dox_command([22, 21, 10], err_inquiry)  # 复位DO5
            injection_port(0)  # 切换阀复位,X-0指令
            time.sleep(3)
            if insert_database() == "004d":  # 查询指令
                sql_insert_suc("切换阀初始化位置")
                pass  # 成功
            else:
                sql_insert_err("FX—0切换阀初始化故障")  # 可存入数据库
                dox_command([24], err_inquiry)
                return
            while remote_maintenance_t3 < 7:  # t2计数，单位为天
                remote_maintenance_t2 = 0
                remote_maintenance_t2_io = 0
                while remote_maintenance_t2 <= 86400:  # 一天的秒数86400
                    remote_maintenance_t2 = remote_maintenance_t2 + 1
                    time.sleep(1)
                    print(remote_maintenance_t3)
                    if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                        remote_maintenance_status = 0
                        break
                    remote_maintenance_t2_io = remote_maintenance_t2_io + 1
                    if remote_maintenance_t2_io >= 100:
                        remote_maintenance_t2_io = 0
                        io_restart()
                remote_maintenance_t3 = remote_maintenance_t3 + 1
            rm_n = 12

        con = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='!qAz2WsX3edc',
            db='ph',
            charset='utf8'
        )
        cur = con.cursor()
        i2c_41 = cur.execute("SELECT i2c41 FROM i2c order by id desc limit 1")
        i2c_41 = int(cur.fetchone()[0])
        cur.close()
        i2c_41_io_restart = 0
        while i2c_41 <= 70:
            if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
                automatic_cleaning_status = 0
                return
            time.sleep(1)
            print("保护液不足")
            i2c_41_io_restart = i2c_41_io_restart + 1
            if i2c_41_io_restart >= 100:
                i2c_41_io_restart = 0
                print("can通讯复位")
                io_restart()

        if di_location[0:1][0] == '0' or di_location[20:21][0] == '0':
            remote_maintenance_status = 0
            break
        io_restart()
        if rm_n == 12:
            if remote_maintenance_t3 >= 20:
                rm_n = 10
                remote_maintenance_t3 = 0  # t2计数复位


def control():
    global manual_control_status, remote_maintenance_status, automatic_cleaning_status, do_location, err_inquiry
    manual_control_status = 0
    remote_maintenance_status = 0
    automatic_cleaning_status = 0

    dox_command([8], [0])
    while 1:
        if di_location[0:1][0] == "0" and manual_control_status == 0:
            manual_control_status = 1
            print("手动")
            manual_control()

        if di_location[0:1][0] == "1" and di_location[20:21][0] == "1" and remote_maintenance_status == 0:
            remote_maintenance_status = 1
            remote_maintenance_s12_io_t = 0
            print("自动保养")
            remote_maintenance_s12()
            while do_location[22:23][0] == "1" or do_location[23:24][0] == "1":
                time.sleep(1)
                remote_maintenance_s12_io_t = remote_maintenance_s12_io_t + 1
                if remote_maintenance_s12_io_t >= 100:
                    print("自动保养设备故障时io查询重启")
                    io_restart()
                if di_location[0:1][0] == "0":
                    break
            reset_all()
            restart_program()

        if di_location[0:1][0] == "1" and di_location[20:21][0] == "0" and automatic_cleaning_status == 0:
            automatic_cleaning_status = 1
            automatic_cleaning_s11_io_t = 0
            print("自动清洗")
            automatic_cleaning_s11()
            while do_location[22:23][0] == "1" or do_location[23:24][0] == "1":
                time.sleep(1)
                automatic_cleaning_s11_io_t = automatic_cleaning_s11_io_t + 1
                if automatic_cleaning_s11_io_t >= 100:
                    print("自动清洗设备故障时io查询重启")
                    automatic_cleaning_s11_io_t = 0
                    io_restart()
                if di_location[0:1][0] == "0":
                    break
            reset_all()
            restart_program()


threads = []
t1 = threading.Thread(target=io_status)
threads.append(t1)

t2 = threading.Thread(target=control)
threads.append(t2)

t3 = threading.Thread(target=i2c_list)
threads.append(t3)

t4 = threading.Thread(target=DHT11)
threads.append(t4)

if __name__ == "__main__":
    # message_di = 0
    global manual_control_status, remote_maintenance_status, automatic_cleaning_status, do_location, di_location
    global err_inquiry, var_err_inquiry, support_failure, err_inquiry_26, io_status_quit, manual_control_t
    global err_inquiry_27, err_inquiry_28, err_inquiry_29, err_inquiry_8, err_inquiry_12, manual_control_reset_timing
    global status_restart_timing, err_inquiry_22
    status_restart_timing = 1  # 使查询继电器板的接口复位
    io_status_quit = 1  # 查询继电器板的程序退出状态
    manual_control_reset_timing = 0  # 手动程序首次启动复位
    support_failure = 0  # 支架状态判断0
    manual_control_t = 100
    var1, var2 = '00000000000000000000000000000000', '00000000000000000000000000000000'
    data_do, data_di = 0, 0
    var_err_inquiry = [0]
    err_inquiry = ['0', '0', '0', '0', '0', '0', '0', '0']
    err_inquiry_26 = ['0']
    err_inquiry_27 = ['0']
    err_inquiry_28 = ['0']
    err_inquiry_29 = ['0']
    err_inquiry_8 = ['0']
    err_inquiry_12 = ['0']
    err_inquiry_22 = ['0']
    do_location = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
                   '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
    di_location = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
                   '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
    falling_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    rising_edge = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    edge = np.zeros(64, np.int8).reshape(2, 32)  # DI上升/下降沿检测,edge[0,0]第1个up，edge[1,0]第1个down
    time_diff = np.zeros(64, np.float64).reshape(2, 32)  # DI上升/下降沿的触发时间
    l_s_time = np.zeros(64, np.int8).reshape(2, 32)  # 短按判断l_s_time[0]|长按判断l_s_time[1]
    can_open()
    while 1:
        for t in threads:
            t.start()
        for t in threads:
            t.join()

os.system('sudo ifconfig can0 down')
